package menu;

import static game.Configurations.*;
import game.Controls;
import game.Controls.Key;
import game.FontLoader;
import game.LScript;
import static game.TextManager.t;
import images.ImageInfo;
import images.ItemLoader;
import images.MenuLoader;
import images.ShipLoader;
import java.awt.Color;
import java.util.Arrays;
import java.util.HashMap;
import math.Point;
import saves.EntidadeNave;
import saves.Save.QuickAccess;
import saves.SaveManager;
import saves.items.Equipamento.LocalEquip;

/**
 *
 * @author Luan
 */
public class Status implements Menu {

    private Menu parent;
    private EntidadeNave nave;
    private QuickAccess[] quickAccess;
    private int[] tempUpgrades;
    private int selItem, selArea;

    public static final int LINE_HEIGHT = 20;

    public Status() {}

    public Status(EntidadeNave nave) {
        this.nave = nave;
        this.dispose();
    }

    @Override
    public void draw() {
        int descSize = 60, equipsSize = 150;
        MenuLoader.bindTexture();
        int hh = (SCREEN_HEIGHT - 40 - descSize)/2, hw = (SCREEN_WIDTH - 30)/2, uh = SCREEN_HEIGHT - equipsSize - descSize - 40;
        MenuLoader.drawBack(10, 10, hw, hh); //status list
        MenuLoader.drawBack(10, hh + 20, hw, hh); //status sel
        MenuLoader.drawBack(hw + 20, 10, hw, equipsSize); //equips & qa
        MenuLoader.drawBack(hw + 20, equipsSize + 20, hw, uh); //upgrades
        MenuLoader.drawBack(10, SCREEN_HEIGHT - 10 - descSize, SCREEN_WIDTH - 20, descSize); //desc box
        if (selArea == 0 || selArea == 1)
            ImageInfo.drawColorSquare(10, 10, hw, hh, Color.WHITE, false);
        else if (selArea == 2)
            ImageInfo.drawColorSquare(hw + 20, 10, hw, equipsSize, Color.WHITE, false);
        else
            ImageInfo.drawColorSquare(hw + 20, equipsSize + 20, hw, uh, Color.WHITE, false);
        FontLoader.TEXT_BIG.drawString(15, 15, "Attributes");
        FontLoader.TEXT_BIG.drawString(SCREEN_WIDTH/2 + 10, 15, "Equips");
        FontLoader.TEXT_BIG.drawString(SCREEN_WIDTH/2 + 10 + hw/2, 15, "Quick Access");
        FontLoader.TEXT_BIG.drawString(SCREEN_WIDTH/2 + 10, equipsSize + 25, "Upgrades");

        //draw attributes
        for (int i = 0; i < t().ATTRIBUTES.length; i++) {
            int lh = 20 + (i + 1)*2*LINE_HEIGHT, s = 16;
            MenuLoader.bindTexture();
            if (selArea == 0 && selItem == i)
                MenuLoader.drawSel(13, lh, 130, LINE_HEIGHT);
            else if (selArea == 1 && selItem/2 == i)
                MenuLoader.drawSel(160, lh + (selItem % 2 == 1 ? 1 : -1)*LINE_HEIGHT/2, 240, LINE_HEIGHT);
            MenuLoader.drawIcon(i + 6, 15, lh, s);
            FontLoader.TEXT.drawString(20 + s, lh, t().ATTRIBUTES[i][0]);

            FontLoader.TEXT.drawString(120, lh, LScript.format(nave.getAttribute(i, 0)));
            FontLoader.TEXT.drawString(160, lh - LINE_HEIGHT/2, t().ATTRIBUTES[i][1]);
            FontLoader.TEXT.drawString(375, lh - LINE_HEIGHT/2, LScript.format(nave.getAttribute(i, 1)));
            FontLoader.TEXT.drawString(160, lh + LINE_HEIGHT/2, t().ATTRIBUTES[i][2]);
            FontLoader.TEXT.drawString(375, lh + LINE_HEIGHT/2, LScript.format(nave.getAttribute(i, 2)));
        }

        //draw selected
        if (selArea <= 1) {
            int lh = (SCREEN_HEIGHT - 40 - descSize)/2 + 25;
            int c1, c2;
            if (selArea == 0) {
                c1 = selItem;
                c2 = 0;
            } else {
                c1 = selItem/2;
                c2 = selItem%2 + 1;
            }
            FontLoader.TEXT_BIG.drawString(15, lh, t().ATTRIBUTES[c1][c2]);
            int i = 2;
            if (selArea == 0) {
                FontLoader.TEXT.drawString(15, lh + i*LINE_HEIGHT, "Base attribute:");
                int orbs = nave.getOrbs(c1);
                FontLoader.TEXT.drawString(300, lh + i++*LINE_HEIGHT, LScript.format(nave.getStatus(c1) - orbs));
                FontLoader.TEXT.drawString(15, lh + i*LINE_HEIGHT, "+Orbs:");
                MenuLoader.bindTexture();
                for (int j = 0; j < orbs; j++)
                    MenuLoader.drawOrb(c1, 100 + j*20, lh + i*LINE_HEIGHT, 16);
                FontLoader.TEXT.drawString(300, lh + i++*LINE_HEIGHT, "+ " + LScript.format(orbs));
            } else {
                FontLoader.TEXT.drawString(15, lh + i*LINE_HEIGHT, "Base status (" + t().ATTRIBUTES[c1][0] + "):");
                FontLoader.TEXT.drawString(300, lh + i++*LINE_HEIGHT, LScript.format(nave.getAttribute(c1, 0)));
            }

            FontLoader.TEXT.drawString(15, lh + i++*LINE_HEIGHT, "+Equips");
            for (int j = 0; j < LocalEquip.size(); j++)
                if (nave.getEquip(j) != null) {
                    String t = nave.getEquip(j).getEffectsOn(c1, c2);
                    if (t != null) {
                        FontLoader.TEXT.drawString(25, lh + i*LINE_HEIGHT, nave.getEquip(j).getNome());
                        FontLoader.TEXT.drawString(300, lh + i++*LINE_HEIGHT, t);
                    }
                }

            FontLoader.TEXT.drawString(15, lh + i*LINE_HEIGHT, "+Effects");
            String t = nave.getEffectsOn(c1, c2);
            FontLoader.TEXT.drawString(300, lh + i++*LINE_HEIGHT, t == null ? "+ 0" : t);

            FontLoader.TEXT_BOLD.drawString(15, lh + i*LINE_HEIGHT, "Total");
            FontLoader.TEXT.drawString(300, lh + i++*LINE_HEIGHT, LScript.format(nave.getAttribute(c1, c2)));
            
            //last lines
            float f = nave.getAttributeModifier(c1, c2);
            if (f != -1) {
                String c;
                int cn1 = selArea == 0 ? selItem : selItem / 2,
                    cn2 = selArea == 0 ? 0 : 1 + selItem % 2;
                if (cn1 <= 1 && cn2 == 0)
                    c = t().ATT_DES[0];
                else if (cn1 == 0 || cn1 == 3)
                    c = t().ATT_DES[1];
                else if (cn1 == 2)
                    c = t().ATT_DES[2];
                else if (cn1 == 1)
                    c = t().ATT_DES[3];
                else
                    c = t().ATT_DES[4];
                HashMap<String, Object> map = new HashMap<>();
                map.put("att", t().ATTRIBUTES[cn1][cn2]);
                map.put("value", f);
                //special vars
                map.put("unit", c1 == 4 ? c2 == 1 ? "N" : "deg/ms" : c2 == 1 ? "m³" : "kg");
                map.put("total", selItem == 0 ? nave.getVidaAtual() : nave.getEnergiaAtual());
                try {
                    FontLoader.TEXT.drawString(15, SCREEN_HEIGHT - descSize - 5, LScript.parse(c, map));
                } catch (Exception ex) {
                    //todo error pretty it up
                    System.err.println("Invalid language file.");
                }
            } else
                FontLoader.TEXT.drawString(15, SCREEN_HEIGHT - descSize - 5, "This attribute is only used to calculate its secondary attributes.");
        }

        //draw equips & qa
        MenuLoader.bindTexture();
        Point.Inteiro[] eqp = MenuLoader.drawEquips(hw + 15, 40, 32);

        ShipLoader.bindTexture();
        if (nave.getEquip(0) != null) //Carcaça
            ItemLoader.drawEquip(nave.getEquip(0), eqp[0].x, eqp[0].y, 32, 0);
        if (nave.getEquip(1) != null) { //Asa
            ItemLoader.drawEquip(nave.getEquip(1), eqp[1].x, eqp[1].y, 32, 0);
            ItemLoader.drawEquip(nave.getEquip(1), eqp[2].x, eqp[2].y, 32, 1);
        }
        if (nave.getEquip(3) != null) { //Prop Lat
            ItemLoader.drawEquip(nave.getEquip(3), eqp[3].x, eqp[3].y, 32, 0);
            ItemLoader.drawEquip(nave.getEquip(3), eqp[4].x, eqp[4].y, 32, 1);
        }
        if (nave.getEquip(2) != null) //Prop Tras
            ItemLoader.drawEquip(nave.getEquip(2), eqp[5].x, eqp[5].y, 32, 0);
        if (nave.getEquip(4) != null) //Trans Ener
            ItemLoader.drawEquip(nave.getEquip(4), eqp[6].x, eqp[6].y, 32, 0);

        MenuLoader.bindTexture();
        Point.Inteiro[] qap = MenuLoader.drawQuickAccess(3*hw/2 + 15, 45, 32);
        ItemLoader.bindTexture();
        for (int i = 0; i < qap.length; i++)
            if (quickAccess[i] != null)
                quickAccess[i].draw(qap[i].x, qap[i].y, 32, nave);

        if (selArea == 2) {
            Point.Inteiro p;
            if (selItem < LocalEquip.size())
                p = eqp[selItem < 2 || selItem == 3 ? selItem : (selItem == 2 ? 5 : 6)];
            else
                p = qap[selItem - LocalEquip.size()];
            ImageInfo.drawColorSquare(p.x, p.y, 32, 32, Color.WHITE, false);
        }

        //draw upgrades
        int[] ups = nave.getUpgrades();
        int lh = equipsSize + 55, s = 16;
        if (selArea == 3) {
            MenuLoader.bindTexture();
            MenuLoader.drawSel(hw + 25, lh + LINE_HEIGHT*selItem - 2, hw - 10, LINE_HEIGHT);
        }
        int upgradesCount = 0;
        int[] tuo = new int[t().UPGRADES_NAMES.length];
        for (int i = 0; i < ups.length; i++)
            if (ups[i] != 0) {
                tuo[upgradesCount] = i;
                int lhs = lh + LINE_HEIGHT*upgradesCount++;
                ItemLoader.drawUpgrade(i, hw + 30, lhs, s);
                FontLoader.TEXT.drawString(hw + 35 + s, lhs, t().UPGRADES_NAMES[i] + (ups[i] == 1 ? "" : " Lv. " + ups[i]));
            }
        tempUpgrades = new int[upgradesCount];
        tempUpgrades = Arrays.copyOf(tuo, tempUpgrades.length);

        //draw options
        String t = "";
        int lhs = 0;
        if (selArea == 0 && nave.getPontosDisponiveis() > 0) {
            t = "Avaliable points: " + nave.getPontosDisponiveis() + ". Select this to add one point to " + t().ATTRIBUTES[selItem][0] + ".";
            lhs = 15;
        } else if (selArea == 2)
            if (selItem < LocalEquip.size()) {
                if (nave.getEquip(selItem) != null)
                    t = "Remove " + nave.getEquip(selItem).getNome();
            } else
                if (quickAccess[selItem - LocalEquip.size()] != null)
                    t = "Remove " + quickAccess[selItem - LocalEquip.size()].toString();
        FontLoader.TEXT.drawString(15, SCREEN_HEIGHT - descSize - 5 + lhs, t);
    }

    @Override
    public Menu go() {
        if (selArea == 0)
            nave.upgradeStatus(selItem);
        else if (selArea == 2) {
            if (selItem < LocalEquip.size()) {
                if (nave.getEquip(selItem) != null)
                    nave.usar(nave.getEquip(selItem)); //desequipar
            } else
                if (quickAccess[selItem - LocalEquip.size()] != null)
                    quickAccess[selItem - LocalEquip.size()] = null; //remover
        }
        return this;
    }

    @Override
    public Menu back() {
        return parent;
    }

    @Override
    public int getActionCode() {
        return -1; //everything is done internally
    }

    @Override
    public void parse(int code, char c) {
        Key k = Controls.get(code, true);
        if (k == null)
            return;
        switch (k) {
            case SEL_UP: {
                if (selItem > 0)
                    selItem--;
                break;
            }
            case SEL_DOWN: {
                int selMax;
                if (selArea == 0)
                    selMax = t().ATTRIBUTES.length;
                else if (selArea == 1)
                    selMax = t().ATTRIBUTES.length * 2;
                else if (selArea == 2)
                    selMax = LocalEquip.size() + 4; //equips + qa
                else
                    selMax = tempUpgrades.length;
                if (selItem < selMax - 1)
                    selItem++;
                break;
            }
            case SEL_RIGHT: {
                if (selArea < 3) {
                    selArea++;
                    selItem = 0;
                }
                break;
            }
            case SEL_LEFT: {
                if (selArea > 0) {
                    selArea--;
                    selItem = 0;
                }
                break;
            }
            case QA_0: {
                if (selArea == 3)
                    quickAccess[0] = new QuickAccess(tempUpgrades[selItem]);
                break;
            }
            case QA_1: {
                if (selArea == 3)
                    quickAccess[1] = new QuickAccess(tempUpgrades[selItem]);
                break;
            }
            case QA_2: {
                if (selArea == 3)
                    quickAccess[2] = new QuickAccess(tempUpgrades[selItem]);
                break;
            }
            case QA_3: {
                if (selArea == 3)
                    quickAccess[3] = new QuickAccess(tempUpgrades[selItem]);
                break;
            }
        }
    }

    @Override
    public Menu setProfile(SaveManager.Profile save) {
        this.nave = save.getSave().getPlayer();
        this.quickAccess = save.getSave().getQuickAccess();
        this.dispose();
        return this;
    }

    @Override
    public Menu getParent() {
        return this.parent;
    }

    @Override
    public void setParent(Menu parent) {
        this.parent = parent;
    }

    @Override
    public void dispose() {
        this.selItem = this.selArea = 0;
    }

    @Override
    public Menu zerar() {
        this.dispose();
        return this;
    }

}
